package cn.leonis.algorithm.c1.p1;

import cn.leonis.algorithm.lib.StdOut;

/**
 * @author Tobi
 * @date 2021-06-07 10:52
 * 使用递归调用实现二项分布
 */
public class BinomialDistributionSolution {

    public static void main(String[] args) {
        int N = 3;
        int k = 2;
        double p = 0.5;
        StdOut.println(binomial1(N, k, p));
        StdOut.println(binomial2(N, k, p));
    }

    /**
     * 利用递归调用实现
     * @param N
     * @param k
     * @param p
     * @return
     */
    public static double binomial1(int N, int k, double p) {
        if (N == 0 && k == 0) return 1.0;
        if (N < 0 || k < 0) return 0.0;
        return (1.0 - p) * binomial1(N - 1, k, p) + p * binomial1(N - 1, k - 1, p);
    }


    public static double binomial2(int N, int k, double p) {
        double[][] b = new double[N + 1][k + 1];

        for (int i = 0; i <= N; i++) {
            b[i][0] = Math.pow(1.0 - p, i);
        }

        b[0][0] = 1.0;

        for (int i = 1; i <= N; i++) {
            for (int j = 1; j <= k; j++) {
                b[i][j] = p * b[i - 1][j - 1] + (1.0 - p) * b[i - 1][j];
            }
        }

        return b[N][k];
    }

}
